//
//  NetworkManager.swift
//  SwiftDemo
//
//  Created by Steven on 2020/7/30.
//  Copyright © 2020 Steven. All rights reserved.
//

import Foundation
import Alamofire
import UIKit
import SwiftyJSON

typealias successClosure = (APIResultModel) -> (Void)
typealias failClosure = (Any) -> (Void)

public enum APIError {
    case apiError_done  // 请求成功
    case apiError_netError(String) // 请求失败  网络 原因
    case apiError_serverMessage(String)  // 请求失败  服务器原因
}

protocol APIInterfaceProtocol {
    var path:String {get}
    var parameters: [String: String]? { get }
  
}

class NetworkManager {
   
    private static var sharedSessionManager: Session = {
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 0.2//请求超时时间
        return Session(configuration: configuration)
    }()
    
    private static func flowNumber()->String{
        let timeSpan = String.dx_nowTimeWithFormat(format: "yyyyMMddHHmmss")
        let randomNum = String(format: "%d",100000 + (arc4random()%100001))
        let flowNumber = String(format: "%@%@", timeSpan,randomNum)
        return flowNumber
    }
    
    private static func signParamters(params:[String:AnyObject])->Dictionary<String,AnyObject>{
        //参数排序
        var parameters = params
        let keyAray = params.keys.sorted()
        var joinParamsStr = ""
        for key in keyAray {
            var val:AnyObject
            if key == "appMap"{
                val = ((params[key]! as! Dictionary<String,String>) as NSObject).modelToJSONString as AnyObject
                val  = (val as! String).replacingOccurrences(of: "\\/", with: "/") as AnyObject
            }else{
                val = params[key]!
            }
            
            let itemUrl = String(format: "%@=%@", key,val as! String)
            joinParamsStr = String(format: "%@%@|", joinParamsStr,itemUrl)
        }
        //拼接商户的秘钥
        joinParamsStr = String(format: "%@%@", joinParamsStr,API_SECRET_KEY)
        DLog("\n*********拼接用户的秘钥后的管道数据*********:\n \(joinParamsStr)")
        //MD5加密
        let signStr = joinParamsStr.dx_md5
        parameters["sigh"] = signStr as AnyObject
        DLog("\n********完成签名参数***********:\n \(parameters) ")
        return parameters
    }
    
    private static func commonAPIParams()->Dictionary<String,String>{
        let  uesrInfo = UserInfo.instance
        var params = [String : String]()
        params.updateValue(API_UAPKEY, forKey: "uapkey")
        params.updateValue(NetworkManager.flowNumber(), forKey: "flowNo")
        params.updateValue(kPLATFORM_CODE, forKey: "platformCode")
        params.updateValue("2", forKey: "terminalType")
        params.updateValue(String.dx_nowTimeWithFormat(format: kTimeFormat.format_yyyyMdHms.rawValue), forKey: "uapkey")
        params.updateValue(kIP, forKey: "ip")
        params.updateValue(kUUID!, forKey: "mac")
        params.updateValue("1", forKey: "dtype")
        params.updateValue(UIDevice.current.modelName, forKey: "brand")
        params.updateValue(kAppVersion as! String, forKey: "ver")
        if  uesrInfo?.userNo != nil{
            params.updateValue("1", forKey: "userToken")
        }
        return params
    }
    
    private static func postRequest(interface:String,params:Dictionary<String,String>,completion:@escaping successClosure,failed:@escaping failClosure){
        
        var commonParams = commonAPIParams() as [String :AnyObject]
        commonParams.updateValue(interface as AnyObject, forKey: "operation")
        if params.isEmpty {
            commonParams.updateValue(" " as AnyObject, forKey: "appMap")
        }else{
            commonParams["appMap"] = params as AnyObject
        }
        
        //生成签名参数
        let paramDict = signParamters(params: commonParams)
        let headers: HTTPHeaders = [
            "Accept": "application/json,text/json,text/javascript,text/plain,text/html",
            "Content-type" : "application/json"
        ]

        sharedSessionManager.request(API_BASE, method: .post, parameters: paramDict, headers: headers).responseJSON { (respons) in
            switch respons.result{
                
            case .success(let value):
                DLog("接口路径: ||---------" + interface + "------||")
                DLog(JSON(value))
                completion(APIResultModel.deserialize(from: value as? Dictionary) ?? APIResultModel() ) 
                return
            case .failure(let error):
                DLog(String(describing: error))
                failed(error)
                return
            }
        }
    }
    
    static func loadData(api:APIInterfaceProtocol,sucess:@escaping successClosure,failed:@escaping failClosure){
        var parmas = [String:String]()
        _ = api.parameters?.map({ (key,value) in
            if !value.isEmpty{
                parmas.updateValue(value, forKey: key)
            }
        })
        
        NetworkManager.postRequest(interface: api.path, params: parmas, completion: sucess, failed: failed)
    }

}
